package distribution;

import java.util.List;

public class UniGaussian {
	private static final double oneOverRootTwoPi = 1 / (Math.pow(2 * Math.PI, 0.5));
	private static final double minimumVariance = Math.pow(0.0001, 2);
	
	private double mean;
	double deviation;
	
	private double a;
	private double b;
	
	public void train(List<Double> X){
		double EX = EX(X);
		double EXX = EXX(X);
		
		mean = EX;
		double variance = EXX - EX * EX;
		
		if(variance < minimumVariance) {
//			System.out.println("variance less than minimum! " + variance + " < " + minimumVariance);
			variance = minimumVariance;
		}
		
		deviation = Math.pow(variance, 0.5);
		
		a = Math.log(oneOverRootTwoPi / deviation);
		b = 1 / (2 * variance);
	}
	
	public double predict(double x) {
		double dis = x - mean;
		return a - b * dis * dis;
	}
	
	protected double EX(List<Double> X) {
		double result = 0;
		for(double x : X) {
			result += x;
		}
		result = result / X.size();
		return result;
	}
	
	protected double EXX(List<Double> X) {
		double result = 0;
		for(double x : X) {
			result += x * x;
		}
		result = result / X.size();
		return result;
	}
}
